package com.siyoumi.app.sys.notify;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.siyoumi.app.modules.accsuper_admin.service.SvcSysAccspuerConfig;
import com.siyoumi.app.sys.vo.NotifyWxPayResource;
import com.siyoumi.app.sys.vo.NotifyWxPayReturn;
import com.siyoumi.app.sys.vo.NotifyWxPayVo;
import com.siyoumi.component.LogPipeLine;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.controller.ApiController;
import com.siyoumi.entity.SysAccsuperConfig;
import com.siyoumi.util.XJson;
import com.siyoumi.util.XStr;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

//微信支付v3通知
//app_id: app_id
//http://test.xiao-bo.com/123123213/notify/wx_pay
@RestController
@Slf4j
@RequestMapping({"/{appId}/notify/wx_pay"})
public class WxPayNotify
        extends ApiController {

    @SneakyThrows
    @RequestMapping()
    public NotifyWxPayReturn index(@RequestBody(required = false) NotifyWxPayVo vo, @PathVariable String appId) {
        LogPipeLine log = LogPipeLine.ofSys();
        log.setLogMsg("app_id: ", appId);
        log.setLogMsg("input: ", XJson.toJSONString(vo));

        if (XStr.isNullOrEmpty(appId)) { //旧数据
            return NotifyWxPayReturn.getInstance("SUCCESS", "");
        }
        if (vo == null || vo.getResource() == null) {
            return NotifyWxPayReturn.getInstance("ERROR", "ERROR");
        }

        SysAccsuperConfig entity = SvcSysAccspuerConfig.getBean().getEntityByAppId(appId);
        String mchKey = entity.getAconfig_partnerKey();

        //解密
        NotifyWxPayResource resource = vo.getResource();
        String decTxt = decryptToString(mchKey.getBytes(StandardCharsets.UTF_8)
                , resource.getAssociated_data().getBytes(StandardCharsets.UTF_8)
                , resource.getNonce().getBytes(StandardCharsets.UTF_8)
                , resource.getCiphertext());
        JSONObject orderJson = JSON.parseObject(decTxt);
        {
            log.setAppendData("log_str_00", orderJson.getString("out_trade_no")); //订单号
            log.setLogMsg(vo.getCreate_time());
            log.setLogMsg(decTxt);
        }

        NotifyWxPayReturn r = NotifyWxPayReturn.getInstance("SUCCESS", "");
        return r;
    }


    @SneakyThrows
    public String decryptToString(byte[] apiKey, byte[] associatedData, byte[] nonce, String ciphertext) {
        if (apiKey.length != 32) {
            throw new IllegalArgumentException("无效的ApiV3Key，长度必须为32个字节");
        }

        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        SecretKeySpec key = new SecretKeySpec(apiKey, "AES");
        GCMParameterSpec spec = new GCMParameterSpec(128, nonce);

        cipher.init(Cipher.DECRYPT_MODE, key, spec);
        cipher.updateAAD(associatedData);

        return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), StandardCharsets.UTF_8);
    }
}
